<template>
    <div class="sea-uploader">
        <div v-show="valueModel" class="sea-uploader-item">
            <img :src="valueModel" alt="Image preview" class="sea-uploader-image"/>
            <div class="sea-uploader-remove" title="删除" @click="removeImage">
                <i class="fa fa-times-circle-o"></i>
            </div>
        </div>
        <div class="sea-uploader-item" v-show="canUpload">
            <div @click="$refs.input.click()" class="sea-uploader-button">
                <i class="fa fa-fw fa-plus"></i>
                <input ref="input" type="file" :accept="props.accept" :multiple="props.multiple"
                       style="display: none" @change="convertToBase64">
            </div>
        </div>
    </div>

</template>

<script setup lang="ts">
import {computed} from 'vue';
import Layers from "@/lang/layers/index";
import Text from "@/lang/layers/text-utils";

/**
 * 图标上传工具
 *
 * 本质上，这是一个可以将文件转为 base64，之后将文件作为字符串上传的工具，可以上传任意文件；
 *
 * 这是一种非常传统的设计，缺点是，表单整体会变大，浪费一定的流量；
 *
 * 设计背景：GIS 系统中，包含大量的 icon，期望将 icon 作为数据存在数据库中，而不需要额外花费成本去维护这些文件。
 */
interface Props {
    /** v-model 双向绑定字段 */
    modelValue: string;
    /** 文件大小限制（KB），默认 1024（即 1MB） */
    maxSize?: number;
    /** 文件数量限制，默认 1 */
    limit?: number;
    /** 文件类型 */
    accept?: string;
    /** 是否允许多选 */
    multiple?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
    maxSize: 1024, limit: 1, accept: '*', multiple: false
});
// image/
// Emits
const emit = defineEmits(['update:modelValue', 'change']);

// 值双向绑定，这种绑定方式，如果没指定 v-model 无法正常显示
const valueModel = computed({
    get() {
        return props.modelValue;
    },
    set(val) {
        emit('update:modelValue', val);
        emit('change', val);
    }
});

// 是否可上传文件
const canUpload = computed(() => {
    return Layers.isEmpty(valueModel.value);
});

/**
 * 文件转为 base64 字符串
 *
 * @param event change-event
 */
const max = props.maxSize * 1024;
const convertToBase64 = (event) => {
    const file = event.target.files[0];
    if (file) {
        if (file.size > max) {
            Layers.warn('文件大小限制：' + Text.fileSize(max));
        } else {
            const reader = new FileReader();
            reader.onload = (e) => {
                valueModel.value = e.target.result;
            };
            reader.readAsDataURL(file);
        }
        event.target.value = '';
    }
};

/**
 * remove image
 */
const removeImage = () => {
    valueModel.value = '';
};
</script>

<style scoped>
/* 你可以在这里添加你的样式 */
</style>